package com.zq.widget.inverted.game.role;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;

import com.zq.widget.inverted.game.role.anim.Anim;
import com.zq.widget.inverted.game.role.damage.DamageCollisionHandler;
import com.zq.widget.inverted.game.role.impl.effect.Boom;
import com.zq.widget.inverted.game.role.hp.HP;

/**
 * Created by zhangqiang on 2018/3/28.
 */
public abstract class Role {

    private RectF roleBounds = new RectF();
    private RectF canvasBounds = new RectF();
    private Anim anim;
    private boolean isAnimRunning;
    private RoleParent parent;
    private Context context;
    private CollisionHandler collisionHandler;

    public Role(Context context) {
        this.context = context;
        setCollisionHandler(new DamageCollisionHandler());
    }

    protected abstract void onDraw(Canvas canvas);

    @CallSuper
    public boolean isFinish() {
        return anim != null && !isAnimRunning;
    }


    @CallSuper
    public void preDraw(){


    }

    @CallSuper
    public void draw(@NonNull Canvas canvas) {

        if (anim == null) {
            anim = onCreateAnim();
        }
        if (anim != null) {
            isAnimRunning = anim.compute();
            if (!isAnimRunning) {
                return;
            }
        }
        canvasBounds.set(0, 0, canvas.getWidth(), canvas.getHeight());
        if (!isBeyondCanvas()) {
            onDraw(canvas);
        }
    }

    /**
     * 绘制区域
     * @return
     */
    @NonNull
    public RectF bounds() {
        return roleBounds;
    }

    /**
     * 碰撞区域
     * @return
     */
    @NonNull
    public RectF collisionBounds(){
        return roleBounds;
    }

    /**
     * 碰撞回调
     * @param target 碰撞的role
     */
    public void onCollisionWith(@NonNull Role target){

        if(collisionHandler != null){
            collisionHandler.handleCollision(this,target);
        }
    }


    public void updateLocation(float left, float top, float right, float bottom) {

        bounds().set(left, top, right, bottom);
    }

    public void updateLocation(PointF pointF) {

        updateLocation(pointF.x, pointF.y);
    }

    public void locationOffset(float dx,float dy) {

        bounds().offset(dx,dy);
    }

    public void resetSize(float width,float height){

        RectF bounds = bounds();
        bounds.left = bounds.centerX() - width/2;
        bounds.top = bounds.centerY() - height/2;
        bounds.right = bounds.left + width;
        bounds.bottom = bounds.top + height;
    }

    public void updateLocation(float x, float y) {

        RectF bounds = bounds();
        float xOffset = bounds.width() / 2;
        float yOffset = bounds.height() / 2;
        float left = x - xOffset;
        float top = y - yOffset;
        float right = x + xOffset;
        float bottom = y + yOffset;
        updateLocation(left, top, right, bottom);
    }

    public void setBounds(RectF rectF) {
        this.bounds().set(rectF);
    }

    public void setBounds(Rect rect) {
        this.bounds().set(rect);
    }

    public void setBounds(float left, float top, float right, float bottom) {
        this.bounds().set(left, top, right, bottom);
    }

    protected void drawFlag(Canvas canvas, float x, float y, String text, Paint paint) {

        paint.reset();
        paint.setTextSize(28);
        float textWidth = paint.measureText(text);
        canvas.drawText(text, x - textWidth / 2, y - paint.descent(), paint);
        paint.setStrokeWidth(8);
        canvas.drawPoint(x, y, paint);
    }

    /**
     * 是否超出canvas
     *
     * @return
     */
    public boolean isBeyondCanvas() {

        return !canvasBounds.isEmpty() && !RectF.intersects(canvasBounds, bounds());
    }

    /**
     * 是否接触画布边缘
     * @return
     */
    public boolean isContactCanvasBounds(){

        RectF bounds = bounds();
        return !canvasBounds.isEmpty() && (bounds.left <= canvasBounds.left
                || bounds.top <= canvasBounds.top
                || bounds.right >= canvasBounds.right
                || bounds.bottom >= canvasBounds.bottom);
    }

    /**
     * 创建动画
     *
     * @return
     */
    protected Anim<?> onCreateAnim() {
        return null;
    }

    public RoleParent getParent() {

        return this.parent;
    }

    public void setParent(RoleParent parent) {

        if (this.parent != null && parent != null) {
            throw new RuntimeException("this role already has a parent : " + this.parent);
        }
        this.parent = parent;
    }

    public Context getContext() {
        return context;
    }


    /**
     * 被移除时回调
     */
    protected void onRemove() {

        RoleParent parent = getParent();
        if(parent == null){
            return;
        }
        if(this instanceof HP && ((HP) this).getHp() <= 0){

            Boom boom = new Boom(getContext());
            boom.updateLocation(this.bounds().centerX(),this.bounds().centerY());
            parent.addChild(boom);
        }
    }

    public void setCollisionHandler(CollisionHandler collisionHandler) {
        this.collisionHandler = collisionHandler;
    }

    public CollisionHandler getCollisionHandler() {
        return collisionHandler;
    }

    /**
     * 碰撞处理接口
     */
    public interface CollisionHandler{

        /**
         * 处理碰撞
         * @param src
         * @param target
         */
        void handleCollision(Role src,Role target);
    }
}
